<template>
  <el-dialog
    :title="title"
    :visible="visible"
    :before-close="handleClose"
    width="40%"
  >
    <el-form ref="form" :model="form" :rules="rules" label-width="110px">
      <el-row v-for="item in searchConfig" :key="item.label">
        <el-col :span="24">
          <el-form-item :label="item.label" :prop="item.value">
            <component :is="item.component" v-model="form[item.value]">
              <el-options v-if="item.component === 'el-select'"></el-options>
            </component>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button @click="cancel">取消</el-button>
      <el-button type="primary" @click="confirm">确定</el-button>
    </template>
  </el-dialog>
</template>

<script>
export default {
  props: {
    modal: {
      type: Object,
    },
    rules: {
      type: Object,
    },
    searchConfig: {
      type: Array,
    },
    addApi: {
      type: Function,
    },
    editApi: {
      type: Function,
    },
  },
  watch: {
    modal: {
      handler(val) {
        this.form = { ...val };
      },
      immediate: true,
    },
  },
  computed: {
    title() {
      switch (this.editType) {
        case "add":
          return "新增";
        default:
          return "编辑";
      }
    },
  },
  data() {
    return {
      visible: false,
      form: null,
      editType: "add",
    };
  },
  methods: {
    changeVisible() {
      this.visible = !this.visible;
    },
    handleClose() {
      this.cancel();
    },
    open(type) {
      this.editType = type;
      this.changeVisible();
    },
    cancel() {
      this.changeVisible();
      this.$emit("cancel");
    },
    confirm() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          const api = this.editType === "add" ? this.addApi : this.editApi;
          const data = await api({ ...this.form });
          this.$message.success("操作成功");
          this.cancel();
          this.$emit("success");
        }
      });
    },
  },
};
</script>

<style></style>
